/**
 * 埋点服务类 - 负责事件创建、验证和上下文管理
 * @author lhx
 */

// 导入React Native的Platform模块，用于获取当前运行平台信息（iOS/Android）
import { Platform } from 'react-native';
// 导入设备信息库（已注释，需要时可启用获取真实设备信息）
// import DeviceInfo from 'react-native-device-info';
// 导入埋点相关的类型定义
import { 
  TrackingEvent,          // 基础埋点事件类型
  ClickTrackingEvent,     // 点击事件类型
  EventType,              // 事件类型枚举
  EventPriority,          // 事件优先级枚举
  EventContext,           // 事件上下文类型
  ClickEventProperties    // 点击事件属性类型
} from '../types/trackingTypes';

// 埋点服务类，使用单例模式确保全应用只有一个服务实例
class TrackingServiceLhx {
  // 静态实例变量，存储唯一的服务实例
  private static instance: TrackingServiceLhx;
  // 当前会话ID，用于标识用户的一次应用使用会话
  private sessionId: string = '';
  // 用户ID，可选，用于标识具体用户
  private userId?: string;
  // 设备唯一标识符，用于设备级别的数据统计
  private deviceId: string = '';
  // 应用版本号，用于版本相关的数据分析
  private appVersion: string = '';

  // 私有构造函数，防止外部直接实例化，确保单例模式
  private constructor() {
    // 调用初始化方法
    this.init();
  }

  // 静态方法获取服务实例，实现单例模式
  public static getInstance(): TrackingServiceLhx {
    // 如果实例不存在，则创建新实例
    if (!TrackingServiceLhx.instance) {
      TrackingServiceLhx.instance = new TrackingServiceLhx();
    }
    // 返回唯一实例
    return TrackingServiceLhx.instance;
  }

  /**
   * 初始化服务
   */
  private async init(): Promise<void> {
    try {
      // 生成新的会话ID，标识本次应用启动会话
      this.sessionId = this.generateSessionId();
      
      // 获取真实设备信息（需要安装 react-native-device-info 库）
      // this.deviceId = await DeviceInfo.getUniqueId();
      // this.appVersion = DeviceInfo.getVersion();
      
      // 临时使用随机生成的设备ID（开发阶段使用）
      this.deviceId = `device_${Math.random().toString(36).substring(2)}`;
      // 设置默认应用版本号
      this.appVersion = '1.0.0';
      
      // 输出初始化成功日志，显示生成的会话ID
      console.log('[TrackingServiceLhx] Initialized with session:', this.sessionId);
    } catch (error) {
      // 捕获初始化过程中的异常，记录错误日志
      console.error('[TrackingServiceLhx] Init error:', error);
      // 设置备用默认值，确保服务能正常工作
      this.deviceId = 'unknown';
      this.appVersion = '1.0.0';
    }
  }

  /**
   * 设置用户ID
   */
  public setUserId(userId: string): void {
    // 保存用户ID到实例变量中
    this.userId = userId;
    // 输出用户ID设置成功的日志
    console.log('[TrackingServiceLhx] User ID set:', userId);
  }

  /**
   * 获取当前会话ID
   */
  public getSessionId(): string {
    // 返回当前会话的ID
    return this.sessionId;
  }

  /**
   * 创建点击事件
   */
  public createClickEvent(
    eventName: string,                        // 事件名称，如"car_card_click"
    properties: ClickEventProperties = {},    // 点击事件的自定义属性
    options: {                               // 可选配置参数
      priority?: EventPriority;              // 事件优先级
      page?: string;                         // 所在页面
      module?: string;                       // 所属模块
      referrer?: string;                     // 来源页面
      experiment?: string;                   // A/B测试标识
    } = {}
  ): ClickTrackingEvent {
    
    // 创建事件上下文信息，包含页面、模块等环境信息
    const context = this.createEventContext(
      options.page || 'unknown',             // 页面名称，默认为'unknown'
      options.module || 'recommendation',    // 模块名称，默认为'recommendation'
      options.referrer,                      // 来源页面
      options.experiment                     // 实验标识
    );

    // 构造完整的点击事件对象
    const event: ClickTrackingEvent = {
      id: this.generateEventId(),                           // 生成唯一事件ID
      eventName,                                           // 事件名称
      eventType: EventType.CLICK,                          // 事件类型为点击
      priority: options.priority || EventPriority.MEDIUM,  // 优先级，默认为中等
      properties,                                          // 自定义属性
      context,                                             // 事件上下文
      timestamp: Date.now(),                               // 当前时间戳
      uploaded: false,                                     // 初始未上传状态
      retryCount: 0                                        // 重试次数初始为0
    };

    // 返回创建的点击事件
    return event;
  }

  /**
   * 创建基础事件
   */
  public createEvent(
    eventName: string,
    eventType: EventType,
    properties: any = {},
    options: {
      priority?: EventPriority;
      page?: string;
      module?: string;
      referrer?: string;
      experiment?: string;
    } = {}
  ): TrackingEvent {
    
    const context = this.createEventContext(
      options.page || 'unknown',
      options.module || 'recommendation',
      options.referrer,
      options.experiment
    );

    const event: TrackingEvent = {
      id: this.generateEventId(),
      eventName,
      eventType,
      priority: options.priority || EventPriority.MEDIUM,
      properties,
      context,
      timestamp: Date.now(),
      uploaded: false,
      retryCount: 0
    };

    return event;
  }

  /**
   * 验证事件数据
   */
  public validateEvent(event: TrackingEvent): boolean {
    // 基本字段验证
    if (!event.id || !event.eventName || !event.eventType) {
      console.warn('[TrackingServiceLhx] Invalid event: missing required fields');
      return false;
    }

    // 时间戳验证
    if (!event.timestamp || event.timestamp <= 0) {
      console.warn('[TrackingServiceLhx] Invalid event: invalid timestamp');
      return false;
    }

    // 上下文验证
    if (!event.context || !event.context.sessionId || !event.context.deviceId) {
      console.warn('[TrackingServiceLhx] Invalid event: missing context');
      return false;
    }

    // 事件名称格式验证
    if (!/^[a-zA-Z0-9_]+$/.test(event.eventName)) {
      console.warn('[TrackingServiceLhx] Invalid event: invalid event name format');
      return false;
    }

    return true;
  }

  /**
   * 过滤敏感信息
   */
  public sanitizeEvent(event: TrackingEvent): TrackingEvent {
    const sanitizedEvent = { ...event };
    
    // 移除敏感字段
    const sensitiveFields = ['password', 'token', 'secret', 'key'];
    
    if (sanitizedEvent.properties) {
      sensitiveFields.forEach(field => {
        if (sanitizedEvent.properties[field]) {
          delete sanitizedEvent.properties[field];
        }
      });
    }

    // 脱敏用户ID（如果需要）
    if (sanitizedEvent.context.userId) {
      // 这里可以添加用户ID脱敏逻辑
      // sanitizedEvent.context.userId = this.hashUserId(sanitizedEvent.context.userId);
    }

    return sanitizedEvent;
  }

  /**
   * 获取页面信息
   */
  public getCurrentPage(): string {
    // 这里可以集成导航状态获取当前页面
    // 目前返回一个默认值，实际使用时需要集成路由
    return 'recommendation_home';
  }

  /**
   * 生成事件唯一ID
   */
  private generateEventId(): string {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).substring(2);
    return `evt_${timestamp}_${random}`;
  }

  /**
   * 生成会话ID
   */
  private generateSessionId(): string {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).substring(2);
    return `session_${timestamp}_${random}`;
  }

  /**
   * 创建事件上下文
   */
  private createEventContext(
    page: string,
    module: string,
    referrer?: string,
    experiment?: string
  ): EventContext {
    return {
      page,
      module,
      platform: Platform.OS as 'android' | 'ios',
      deviceId: this.deviceId,
      appVersion: this.appVersion,
      timestamp: Date.now(),
      sessionId: this.sessionId,
      userId: this.userId,
      referrer,
      experiment
    };
  }

  /**
   * 重新生成会话ID（用于新会话）
   */
  public renewSession(userId?: string): string {
    this.sessionId = this.generateSessionId();
    this.userId = userId;
    console.log('[TrackingServiceLhx] New session created:', this.sessionId);
    return this.sessionId;
  }

  /**
   * 获取设备信息
   */
  public getDeviceInfo(): {
    deviceId: string;
    platform: string;
    appVersion: string;
  } {
    return {
      deviceId: this.deviceId,
      platform: Platform.OS,
      appVersion: this.appVersion
    };
  }

  /**
   * 调试方法：打印事件信息
   */
  public debugEvent(event: TrackingEvent): void {
    if (__DEV__) {
      console.group(`[TrackingServiceLhx] Event: ${event.eventName}`);
      console.log('Event ID:', event.id);
      console.log('Event Type:', event.eventType);
      console.log('Priority:', event.priority);
      console.log('Properties:', event.properties);
      console.log('Context:', event.context);
      console.log('Timestamp:', new Date(event.timestamp).toISOString());
      console.groupEnd();
    }
  }
}

export default TrackingServiceLhx;